/*
 * CCVisu is a tool for visual graph clustering
 * and general force-directed graph layout.
 * This file is part of CCVisu.
 *
 * Copyright (C) 2005-2011  Dirk Beyer
 *
 * CCVisu is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * CCVisu is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with CCVisu; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Please find the GNU Lesser General Public License in file
 * license_lgpl.txt or http://www.gnu.org/licenses/lgpl.txt
 *
 * Dirk Beyer    (firstname.lastname@uni-passau.de)
 * University of Passau, Bavaria, Germany
 */
package org.sosy_lab.ccvisu.readers;

import java.io.BufferedReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.util.logging.Level;

import org.sosy_lab.ccvisu.graph.GraphData;
import org.sosy_lab.ccvisu.graph.GraphVertex;
import org.sosy_lab.ccvisu.graph.Group;
import org.sosy_lab.ccvisu.writers.WriterDataLayoutDISP;
import org.sosy_lab.common.LogManager;
import org.sosy_lab.util.Colors;

/**
 * A class that save and load group information in WriterDataGraphicsDISP
 */
public class ReaderWriterGroup {
  /*
   * the file are in text format of the form:
   *
   * group1.name \t color \t visible \t info
   * \t node1.name
   * \t node2.name
   * \t ...
   * group2.name \t color \t visible \t info
   * ...
   *
   * see class Group for informations about the fields
   */

  /**
   * read from a stream, build the groups and put them in the Writer...DISP
   * @param logger the log manager
   * @param reader the input stream
   * @param writer the WriterDataGraphicsDISP that contains the group
   */
  public static void read(LogManager logger, BufferedReader reader,
      WriterDataLayoutDISP writer) {

    assert(logger != null && reader != null && writer != null);

    //remove all existing groups (except default)
    while (writer.getGraph().getNumberOfGroups() > 1) {
      writer.getGraph().removeGroup(1);
    }

    try {
      Group currentGroup = null;
      String line = null;
      GraphData graph = writer.getGraph();
      while ((line = reader.readLine()) != null) {
        //vertex
        if (line.length() > 0 && line.charAt(0) == '\t') {
          String name = line.substring(1, line.length());
          GraphVertex currentVertex = graph.getVertexByName(name);
          if (currentVertex != null) {
            currentGroup.addNode(currentVertex);
          }
        } else {
          //group
          StringTokenizer st = new StringTokenizer(line, "\t");
          currentGroup = new Group(st.nextToken(), writer.getGraph());
          currentGroup.setColor(Colors.valueOfUpper(st.nextToken()).get());
          currentGroup.setVisible((Boolean.valueOf(st.nextToken())).booleanValue());
          currentGroup.setInfo((Boolean.valueOf(st.nextToken())).booleanValue());
          writer.getGraph().addGroup(currentGroup);
        }
      }
    } catch (Exception e) {
      logger.logUserException(Level.SEVERE, e,
          "Exception while reading (ReaderWriterGroup.read)");
    }
  }

  /**
   * write on a stream the informations needed to rebuild the groups later
   * @param out    the output stream
   * @param writer the WriterDataGraphicsDISP that contains the group
   */
  public static void write(PrintWriter out, WriterDataLayoutDISP writer) {
    assert(out != null && writer != null);

    int end = writer.getGraph().getNumberOfGroups();
    for (int i = 1; i < end; i++) {
      //begin at 1 => ignore default group
      Group group = writer.getGraph().getGroup(i);
      out.println(group.getName() + "\t"
          + (group.getColor().toString()) + "\t"
          + group.isVisible() + "\t" + group.isInfo());

      for (GraphVertex vertex : group) {
        out.println("\t" + vertex.getName());
      }
    }
  }
}
